/* classifies a poker hand*/

/*
    4个花色和（2，3，4，5，6，7，8，9，10，j，q，k，a）共13个等级。
    五张牌有以下类别：
    同花顺(顺子且花色一样)
    炸弹(4张等级一样)
    葫芦(3张牌花色一样，另外两张花色一样)
    
    同花(五张牌花色一样)
    顺子(五张等级相连)

    三张(三张等级一样)
    两对()
    一对(两张等级一样)
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define NUM_RANKS 13
#define NUM_SUITS 4
#define NUM_CARDS 5

/* external variables */
int num_in_rank[NUM_RANKS];/* 每一个等级的个数 */
int num_in_suit[NUM_SUITS];/* 每一个花色的个数 */
bool straight, flush, four, three;
int pairs;  /* can be 0, 1 or 2 */

/* prototypes */
void read_cards(void);
void analyze_hand(void);
void print_result(void);

int main(void)
{
    for (;;) {
        read_cards();
        analyze_hand();
        print_result();
    }
}

void read_cards(void)
{
    bool card_exists[NUM_RANKS][NUM_SUITS];
    char ch,rank_ch,suit_ch;
    int rank,suit;

    bool bad_card;
    int cards_read = 0;

    for (rank = 0; rank < NUM_RANKS; rank++){
        num_in_rank[rank] = 0;
        for(suit = 0; suit < NUM_SUITS; suit++){
            card_exists[rank][suit] = false;
        }
    }

    for(suit = 0; suit < NUM_SUITS; suit++)
        num_in_suit[suit] = 0;

        
    while(cards_read < NUM_CARDS){
        bad_card = false;

        printf("Enter a card: ");
        
        rank_ch = getchar();
        switch(rank_ch){
            case '0':   exit(EXIT_SUCCESS);//退出
            case '2':   rank = 0;break;
            case '3':   rank = 1;break;
            case '4':   rank = 2;break;
            case '5':   rank = 3;break;
            case '6':   rank = 4;break;
            case '7':   rank = 5;break;
            case '8':   rank = 6;break;
            case '9':   rank = 7;break;
            case 't': case 'T':   rank = 8; break;
            case 'j': case 'J':   rank = 9; break;
            case 'q': case 'Q':   rank = 10; break;
            case 'k': case 'K':   rank = 11; break;
            case 'a': case 'A':   rank = 12; break;
            default:     bad_card = true;
        }

        suit_ch = getchar();
        switch(suit_ch){
            case 'c':case 'C':   suit = 0;break;
            case 'd':case 'D':   suit = 1;break;
            case 'h':case 'H':   suit = 2;break;
            case 's':case 'S':   suit = 3;break;
            default:     bad_card = true;
        }
        while( (ch = getchar()) != '\n' )
            if ( ch != ' ' ) bad_card = true;
        
        if (bad_card)
            printf("Bad card; ignored.\n");
        else if (card_exists[rank][suit])
            printf("Duplicate card; ignored.");
        else{
            num_in_rank[rank]++;
            num_in_suit[suit]++;
            card_exists[rank][suit] = true;
            cards_read++;

        }
    }
}

void analyze_hand(void)
{
    int num_consec = 0;
    int rank, suit;
    
    straight = false;/* 顺子 */
    flush = false;/* 同花 */
    four = false;/* 炸弹 */
    three = false;/* 三张 */
    pairs = 0;/* 两对 */

    /* check for flush */
    /* 五张牌花色一样 */
    for (suit = 0; suit < NUM_SUITS; suit++)
        if (num_in_suit[suit] == NUM_CARDS)
            flush = true;

    /* check for straight */
    /* 检查是不是顺子 */
    rank = 0;
    while (num_in_rank[rank] == 0) rank++;
    for (; rank < NUM_RANKS && num_in_rank[rank] > 0; rank++)
        num_consec++;
    if(num_consec == NUM_CARDS){
        straight = true;
        return;
    }

    /* check for 4-of-a-kind, 3-of-a-kind, and pairs */
    for (rank = 0; rank < NUM_RANKS; rank++)
    {
        if (num_in_rank[rank] == 4)
            four = true;
        if (num_in_rank[rank] == 3)
            three = true;
        if (num_in_rank[rank] == 2)
            pairs++;
    }

}

void print_result(void)
{
    if (straight && flush)
        printf("Straight flush!\n");
    else if (four)
        printf("Four of a kind!\n");
    else if(three && pairs == 1)
        printf("Full house!\n");
    else if (flush)
        printf("Flush");
    else if(straight)
        printf("Straight!\n");
    else if(three)
        printf("Three of a kind!\n");
    else if(pairs == 2)
        printf("Two pairs!\n");
    else if(pairs == 1)
        printf("One pair!\n");
    else
        printf("High card!\n");
    
    printf("\n\n");
        
}